{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "eadfbfb7-f37b-46d6-823e-83f3bb557a68",
   "metadata": {},
   "source": [
    "# NumPy3\n",
    "\n",
    "## 向量运算\n",
    "\n",
    "绝大多数向量运算都是每个元素分别进行运算，最后的结果还是向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ffde888b-74e8-4285-9618-9d3476d41df1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "669248cd-a74c-4877-be1d-a360cf19e58a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 2, 3, 4, 5, 6, 7, 8, 9]),\n",
       " array([11, 12, 13, 14, 15, 16, 17, 18, 19]),\n",
       " array([10, 20, 30, 40, 50, 60, 70, 80, 90]))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 向量和标量的加法、乘法运算\n",
    "array1 = np.arange(1, 10)\n",
    "array1, array1 + 10, array1 * 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f8119f51-3962-4776-a9c6-96b6773d20ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([False, False, False, False, False,  True,  True,  True,  True]),\n",
       " array([False,  True, False,  True, False,  True, False,  True, False]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 布尔运算\n",
    "array1 > 5,  array1 % 2 == 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "93d0aadf-4d7b-4d15-9bd4-eb9e338b51ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 2, 3, 4, 5, 6, 7, 8, 9]), array([1, 1, 1, 2, 2, 2, 3, 3, 3]))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array2 = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3])\n",
    "array1, array2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "59d6b1c4-2d69-43df-a6c6-cd35569a8c54",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 2,  3,  4,  6,  7,  8, 10, 11, 12]),\n",
       " array([ 1,  2,  3,  8, 10, 12, 21, 24, 27]),\n",
       " array([  1,   2,   3,  16,  25,  36, 343, 512, 729]))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 向量加法、乘法、幂运算\n",
    "array1 + array2, array1 * array2, array1 ** array2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f2b29faf-308b-47ea-858d-3ace44ceaa3f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([False,  True,  True,  True,  True,  True,  True,  True,  True]),\n",
       " array([ True,  True,  True,  True, False,  True, False, False,  True]))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 布尔运算\n",
    "array1 > array2, array1 % array2 == 0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff42708c-a5b6-47b1-a9e3-e2113427c0d0",
   "metadata": {},
   "source": [
    "## 数学函数\n",
    "\n",
    "### 一元函数\n",
    "\n",
    "| 函数                             | 说明                                          |\n",
    "| -------------------------------- | --------------------------------------------- |\n",
    "| `abs` / `fabs`                   | 求绝对值的函数                                |\n",
    "| `sqrt`                           | 求平方根的函数，相当于`array ** 0.5 `         |\n",
    "| `square`                         | 求平方的函数，相当于`array ** 2`              |\n",
    "| `exp`                            | 计算 $\\small{e^x}$ 的函数                               |\n",
    "| `log` / `log10` / `log2`         | 对数函数（`e`为底 / `10`为底 / `2`为底）      |\n",
    "| `sign`                           | 符号函数（`1` - 正数；`0` - 零；`-1` - 负数） |\n",
    "| `ceil` / `floor`                 | 上取整 /  下取整                              |\n",
    "| `isnan`                          | 返回布尔数组，NaN对应`True`，非NaN对应`False` |\n",
    "| `isfinite` / `isinf`             | 判断数值是否为无穷大的函数                    |\n",
    "| `cos` / `cosh` / `sin`           | 三角函数                                      |\n",
    "| `sinh` / `tan` / `tanh`          | 三角函数                                      |\n",
    "| `arccos` / `arccosh` / `arcsin`  | 反三角函数                                    |\n",
    "| `arcsinh` / `arctan` / `arctanh` | 反三角函数                                    |\n",
    "| `rint` / `round`                 | 四舍五入函数                                  |\n",
    "### 二元函数\n",
    "\n",
    "传入2个N维数组，对应位置的元素进行运算\n",
    "\n",
    "| 函数                               | 说明                                                         |\n",
    "| ---------------------------------- | ------------------------------------------------------------ |\n",
    "| `add(x, y)` / `substract(x, y)`    | 加法函数 / 减法函数                                          |\n",
    "| `multiply(x, y)` / `divide(x, y)`  | 乘法函数 / 除法函数                                          |\n",
    "| `floor_divide(x, y)` / `mod(x, y)` | 整除函数 / 求模函数                                          |\n",
    "| `allclose(x, y)`                   | 检查数组`x`和`y`元素是否几乎相等                             |\n",
    "| `power(x, y)`                      | 数组`x`的元素 $\\small{x_{i}}$ 和数组`y`的元素 $\\small{y_{i}}$，计算 $\\small{x_{i}^{y_{i}}}$ |\n",
    "| `maximum(x, y)` / `fmax(x, y)`     | 两两比较元素获取最大值 / 获取最大值（忽略NaN）               |\n",
    "| `minimum(x, y)` / `fmin(x, y)`     | 两两比较元素获取最小值 / 获取最小值（忽略NaN）               |\n",
    "| `dot(x, y)`                        | 点积运算（数量积，通常记为 $\\small{\\cdot}$ ，用于欧几里得空间（Euclidean space）） |\n",
    "| `inner(x, y)`                      | 内积运算（内积的含义要高于点积，点积相当于是内积在欧几里得空间 $\\small{\\mathbb{R}^{n}}$ 的特例，而内积可以推广到赋范向量空间，只要它满足平行四边形法则即可） |\n",
    "| `cross(x, y) `                     | 叉积运算（向量积，通常记为 $\\small{\\times}$ ，运算结果是一个向量）     |\n",
    "| `outer(x, y)`                      | 外积运算（张量积，通常记为 $\\small{\\bigotimes}$ ，运算结果通常是一个矩阵） |\n",
    "| `intersect1d(x, y)`                | 计算`x`和`y`的交集，返回这些元素构成的有序数组               |\n",
    "| `union1d(x, y)`                    | 计算`x`和`y`的并集，返回这些元素构成的有序数组               |\n",
    "| `in1d(x, y)`                       | 返回由判断`x` 的元素是否在`y`中得到的布尔值构成的数组        |\n",
    "| `setdiff1d(x, y)`                  | 计算`x`和`y`的差集，返回这些元素构成的数组                   |\n",
    "| `setxor1d(x, y)`                   | 计算`x`和`y`的对称差，返回这些元素构成的数组                 |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "342ad26a-a8cc-491b-936a-0cb4c79a389d",
   "metadata": {},
   "source": [
    "## 广播机制\n",
    "\n",
    "数组运算，两个数组形状不同时，会触发广播机制。缺失的行或列会自动复制已有的行和列进行填充。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "864683d8-09ee-472a-96ea-2a48f924c617",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[0, 0, 0],\n",
       "        [1, 1, 1],\n",
       "        [2, 2, 2],\n",
       "        [3, 3, 3]]),\n",
       " array([1, 2, 3]),\n",
       " array([[1, 2, 3],\n",
       "        [2, 3, 4],\n",
       "        [3, 4, 5],\n",
       "        [4, 5, 6]]))"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array5 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])\n",
    "array6 = np.array([1, 2, 3])\n",
    "array5, array6, array5 + array6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "31b45d70-bdac-4167-b1a2-d83e0d7efdd1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2, 3, 4],\n",
       "       [3, 4, 5],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array7 = np.array([[1], [2], [3]])\n",
    "array6 + array7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a355522-d7fa-4d37-a560-c6750dcecf6c",
   "metadata": {},
   "source": [
    "## 常用函数\n",
    "\n",
    "\n",
    "| 函数                           | 说明                                             |\n",
    "| ------------------------------ | ------------------------------------------------ |\n",
    "| `unique`                       | 去除数组重复元素，返回唯一元素构成的有序数组     |\n",
    "| `copy`                         | 返回拷贝数组得到的数组                           |\n",
    "| `sort`                         | 返回数组元素排序后的拷贝                         |\n",
    "| `split` / `hsplit` / `vsplit`  | 将数组拆成若干个子数组                           |\n",
    "| `stack` / `hstack` / `vstack`  | 将多个数组堆叠成新数组                           |\n",
    "| `concatenate`                  | 沿着指定的轴连接多个数组构成新数组               |\n",
    "| `append` / `insert`            | 向数组末尾追加元素 / 在数组指定位置插入元素      |\n",
    "| `argwhere`                     | 找出数组中非0元素的位置                          |\n",
    "| `extract` / `select` / `where` | 按照指定的条件从数组中抽取或处理数组元素         |\n",
    "| `flip`                         | 沿指定的轴翻转数组中的元素                       |\n",
    "| `fromregex`                    | 通过读取文件和正则表达式解析获取数据创建数组对象 |\n",
    "| `repeat` / `tile`              | 通过对元素的重复来创建新数组                     |\n",
    "| `roll`                         | 沿指定轴对数组元素进行移位                       |\n",
    "| `resize`                       | 重新调整数组的大小                               |\n",
    "| `place` / `put`                | 将数组中满足条件的元素/指定的元素替换为指定的值  |\n",
    "| `partition`                    | 用选定的元素对数组进行一次划分并返回划分后的数组 |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "4bc0be91-1299-43e0-bb40-bc4cac2bd355",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0],\n",
       "       [1, 1, 1],\n",
       "       [2, 2, 2],\n",
       "       [3, 3, 3]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "258838de-0e17-41b6-8a88-97a094781044",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 去重，得到向量\n",
    "np.unique(array5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "aca07682-3596-4534-8180-e57ff73dcd88",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 1, 1, 4, 4, 4],\n",
       "       [2, 2, 2, 5, 5, 5],\n",
       "       [3, 3, 3, 6, 6, 6]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 水平拼接数组\n",
    "array8 = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])\n",
    "array9 = np.array([[4, 4, 4], [5, 5, 5], [6, 6, 6]])\n",
    "np.hstack((array8, array9))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f5809ded-3ff1-46ec-b54d-17401fa9ef49",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 1, 1],\n",
       "       [2, 2, 2],\n",
       "       [3, 3, 3],\n",
       "       [4, 4, 4],\n",
       "       [5, 5, 5],\n",
       "       [6, 6, 6]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 垂直拼接数组\n",
    "np.vstack((array8, array9))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "6506c71f-5465-4302-b776-7f9bd9080377",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[1, 1, 1],\n",
       "        [2, 2, 2],\n",
       "        [3, 3, 3],\n",
       "        [4, 4, 4],\n",
       "        [5, 5, 5],\n",
       "        [6, 6, 6]]),\n",
       " array([[1, 1, 1, 4, 4, 4],\n",
       "        [2, 2, 2, 5, 5, 5],\n",
       "        [3, 3, 3, 6, 6, 6]]))"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 沿着指定轴拼接数组，默认沿0轴\n",
    "np.concatenate((array8, array9)), np.concatenate((array8, array9), axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "f7c4c22e-0a5d-4004-bdb5-ed8b4392f22e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 2, 3, 4, 5, 6, 7, 8, 9]),\n",
       " array([  1,   2,   3,   4,   5,   6,   7,   8,   9,  10, 100]))"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 追加元素\n",
    "array1, np.append(array1, [10, 100])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "aa59787c-2ee0-45be-9857-f053b7846ae2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  1,  98,  99, 100,   2,   3,   4,   5,   6,   7,   8,   9])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在指定位置插入元素\n",
    "np.insert(array1, 1, [98, 99, 100])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "678a50c6-60e9-4154-8d33-3ec23bd7de51",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 3, 5, 7, 9])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 提取元素\n",
    "np.extract(array1 % 2 != 0, array1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "257c1313-b611-4343-b494-3104dab65c00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([10, 20, 30,  0,  0,  0, 49, 64, 81])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 满足条件1的，按照操作1操作，依次类推，其他元素全用0填充\n",
    "np.select(\n",
    "    # 条件1        # 条件2\n",
    "    [array1 <= 3, array1 >= 7],  # 条件\n",
    "    # 操作1        # 操作2\n",
    "    [array1 * 10, array1 ** 2]   # 操作\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "f5aad687-722e-48d3-b786-8c24fcc93e1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8,\n",
       "       8, 8, 9, 9, 9])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 重复元素\n",
    "np.repeat(array1, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "cbf847d5-39be-48c0-bd11-d09f4b84b10e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 重复数组\n",
    "np.tile(array1, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "fef8b37a-a151-4b7d-9bc7-74ec3d70a0d3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 2, 3, 4, 5, 6, 7, 8, 9]),\n",
       " array([[1, 2, 3],\n",
       "        [4, 5, 6],\n",
       "        [7, 8, 9],\n",
       "        [1, 2, 3],\n",
       "        [4, 5, 6]]))"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 修改数组形状\n",
    "array1, np.resize(array1, (5, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "ee0cb023-3e19-4108-83d3-7fb92f667ef0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([100, 200,   3, 200,   5, 100,   7,   8, 100])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 批量修改数组元素\n",
    "np.put(array1, \n",
    "       [0, 1, -1, 3, 5],  # 索引\n",
    "       [100, 200]         # 值，轮流使用\n",
    "      )\n",
    "array1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "2cd52bb4-d93c-498f-afca-50a2d0d871c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 3, 5, 1, 2, 3, 1])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 批量修改数组\n",
    "np.place(array1,\n",
    "         array1 > 5,  # 条件\n",
    "         [1, 2, 3]    # 值，轮流使用\n",
    "        )\n",
    "array1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffe43067-f7f2-4274-af5d-981cf54b0fc3",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
